package com.googlecode.moneyManager.model;

import java.math.BigDecimal;
import java.math.RoundingMode;

import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Transient;

import org.hibernate.annotations.Type;

/**
 * @author Sergiy Doroshenko
 */
@Entity
public class Amount extends BaseEntity{
  
    private BigDecimal amount;

    private Currency currency;
    
    public Amount(){}

    /**
     * @param amount -
     * @param currency -
     */
    public Amount(String amount, Currency currency) {
        this.amount = new BigDecimal(amount);
        this.amount = this.amount.setScale(2, RoundingMode.HALF_UP);
        this.currency = currency;
    }

    public Amount(BigDecimal amount, Currency currency) {
        this.amount = amount.setScale(2, RoundingMode.HALF_UP);
        this.currency = currency;
    }

    /**
     * add two amount if their currency match
     * 
     * @param a1  -
     * @param a2 -
     * @return Amount
     */
    @Transient
    public static Amount add(Amount a1, Amount a2) {
        if (!a1.getCurrency().equals(a2.getCurrency()))
            throw new IllegalArgumentException("amount currency mismatch");
        return new Amount(a1.getAmount().add(a2.getAmount()).setScale(2, RoundingMode.HALF_UP), a1.getCurrency());
    }

    /**
     * @param a -
     */
    @Transient
    public void addToAmount(final Amount a) {
        if (!this.getCurrency().equals(a.getCurrency()))
            throw new IllegalArgumentException("amount currency mismatch");
        this.amount = this.amount.add(a.getAmount()).setScale(2, RoundingMode.HALF_UP);
    }

    /**
     * sub two amount if their currency match
     * 
     * @param a1 -
     * @param a2 -
     * @return Amount
     */
    @Transient
    public static Amount sub(Amount a1, Amount a2) {
        if (!a1.getCurrency().equals(a2.getCurrency()))
            throw new IllegalArgumentException("sub currency mismatch");
        return new Amount(a1.getAmount().subtract(a2.getAmount()).setScale(2, RoundingMode.HALF_UP), a1.getCurrency());
    }
 
    public BigDecimal getAmount() {
        return amount;
    }

    public void setAmount(BigDecimal amount) {
        this.amount = amount.setScale(2, RoundingMode.HALF_UP);
    }
    
    @Type(type = "com.googlecode.moneyManager.model.CurrencyUserType")
    public Currency getCurrency() {
        return currency;
    }

    public void setCurrency(Currency currency) {
        this.currency = currency;
    }

    @Override
    public String toString() {
        return "amount = " + getAmount() + "; currency = " + currency;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Amount amount1 = (Amount) o;

        if (!amount.equals(amount1.amount)) return false;
        if (currency != amount1.currency) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = super.hashCode();
        result = 31 * result + amount.hashCode();
        result = 31 * result + currency.hashCode();
        return result;
    }
}
